package org.spring.bean.factory.config;

import org.spring.bean.exceptions.BeansException;
import org.spring.bean.factory.BeanFactory;
import org.spring.bean.factory.BeanFactoryAware;
import org.spring.bean.factory.ListableBeanFactory;

/**
 * {@link BeanFactory} 接口的扩展，
 * 由能够自动装配的 bean 工厂实现，前提是他们希望为现有的 bean 实例公开此功能。
 * <p>
 * BeanFactory 的这个子接口不适用于普通应用程序代码：对于典型用例，请坚持使用 {@link BeanFactory} 或 {@link ListableBeanFactory}。
 * <p>
 * 其他框架的集成代码可以利用此接口来连接和填充 Spring 不控制其生命周期的现有 bean 实例。
 * 例如，这对于 WebWork Actions 和 Tapestry Page 对象特别有用。
 * <p>
 * 请注意，此接口不是由 {@link ApplicationContext} 门面实现的，因为它几乎不被应用程序代码使用。
 * 也就是说，它也可以从应用程序上下文中获得，可以通过ApplicationContext 的 {@link ApplicationContext#getAutowireCapableBeanFactory()} 方法访问。
 * <p>
 * 您还可以实现 {@link BeanFactoryAware} 接口，即使在 ApplicationContext 中运行时也会公开内部 BeanFactory，
 * 以访问 AutowireCapableBeanFactory：只需将传入的 BeanFactory 转换为 AutowireCapableBeanFactory。
 *
 * @author 李坤
 * @date 2022/4/23 19:03
 */
public interface AutowireCapableBeanFactory extends BeanFactory {

    /**
     * 初始化给定的原始bean，应用工厂回调，例如{@code setBeanName}和{@code setBeanFactory}，也应用所有bean后处理器(包括可能包装给定原始bean的处理器)。
     * <p>
     * 注意，给定名称的bean定义不必存在于bean工厂中。传入的bean名将只用于回调，而不针对已注册的bean定义进行检查。
     *
     * @param existingBean 现有的 bean 实例
     * @param beanName     bean的名称，必要时传递给它(只传递给{@link BeanPostProcessor BeanPostProcessors}；
     *                     可以遵循{@link ORIGINAL_INSTANCE_SUFFIX}的约定，以强制返回给定的实例，即没有代理等)
     *
     * @return 要使用的bean实例，原始的或包装的bean实例
     *
     * @throws BeansException 如果初始化失败
     * @see #ORIGINAL_INSTANCE_SUFFIX
     */
    Object initializeBean(Object existingBean, String beanName) throws BeansException;

    /**
     * 将{@link BeanPostProcessor BeanPostProcessors}应用到给定的现有bean实例，调用它们的{@code postProcessBeforeInitialization}方法。
     * 返回的bean实例可能是原始bean的包装器。
     *
     * @param existingBean 现有的bean实例
     * @param beanName     bean的名称，必要时传递给它(只传递给{@link BeanPostProcessor BeanPostProcessors};
     *                     可以遵循{@link ORIGINAL_INSTANCE_SUFFIX}的约定，以强制返回给定的实例，即没有代理等)
     *
     * @return 要使用的 bean 实例，原始的或包装的 bean 实例
     *
     * @throws BeansException 如果任何后处理失败
     * @see BeanPostProcessor#postProcessBeforeInitialization
     * @see #ORIGINAL_INSTANCE_SUFFIX
     */
    Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException;

    /**
     * 将{@link BeanPostProcessor BeanPostProcessors}应用到给定的现有bean实例，调用它们的{@code postProcessAfterInitialization}方法。
     * 返回的bean实例可能是原始bean的包装器。
     *
     * @param existingBean 现有的 bean 实例
     * @param beanName     bean的名称，必要时传递给它(只传递给{@link BeanPostProcessor BeanPostProcessors};
     *                     可以遵循{@link ORIGINAL_INSTANCE_SUFFIX}的约定，以强制返回给定的实例，即没有代理等)
     *
     * @return the bean instance to use, either the original or a wrapped one
     *
     * @throws BeansException if any post-processing failed
     * @see BeanPostProcessor#postProcessAfterInitialization
     * @see #ORIGINAL_INSTANCE_SUFFIX
     */
    Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException;

}
